package com.rankeiot.platform.service;

import com.rankeiot.core.EasyCorePlugin;
import com.rankeiot.core.data.Pair;
import com.rankeiot.core.data.Item;
import com.rankeiot.core.dict.FixedDictManager;
import com.rankeiot.core.translator.SimpleTranslator;
import com.rankeiot.core.translator.Translator;
import com.rankeiot.core.util.CollectionUtil;
import com.rankeiot.core.util.LocaleUtil;
import com.rankeiot.platform.PlatformModule;
import com.rankeiot.platform.domain.TDictionary;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import org.sagacity.sqltoy.dao.SqlToyLazyDao;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

@Component("dictService")
@RequiredArgsConstructor
public class CacheDataService implements DisposableBean {

    private Map<String, List<Item>> dictCache = new HashMap<>();
    //地区列表
    private Map<String, Item> districts = new HashMap();
    //机构列表
    private Map<String, Item> baranchs = new HashMap();
    final SqlToyLazyDao dao;


    @PostConstruct
    public void init() {
       //PlatformModule.installed)
        if(EasyCorePlugin.hasDataSource){
            buildDictCache();
        }
    }
    /**
     * 获取字典翻译器
     * @param dictType 字典类型
     * @return
     */
    public Translator getDictTranslator(String dictType) {
        return getDictTranslator(dictType,false);
    }
    /**
     * 获取字典翻译器
     * @param dictType 字典类型
     * @param backTranslations 是否反向翻译，即解码，
     *                          如果为true，则为解码，输入字典名，返回字典值
     *                          如果为false，则为编码，输入字典值，返回字典名
     * @return
     */
    public Translator getDictTranslator(String dictType,boolean backTranslations) {
        return new SimpleTranslator((Map)getByType(dictType),backTranslations);
    }
    //建立字典缓存
    public void buildDictCache() {
        Map<String, List<Item>> caches = new HashMap();
        List<Map> dicts = dao.findBySql("select type,sn,name from t_dictionary ORDER BY type,`rank`", new HashMap<>(), Map.class);
        for (Map dictItem : dicts) {
            String type = (String) dictItem.get("type");
            List<Item> subCodes = caches.get(type);
            if (subCodes == null) {
                subCodes = new ArrayList<>();
                caches.put(type, subCodes);
            }
            subCodes.add(new Item((String) dictItem.get("sn"), (String) dictItem.get("name")));
        }

        List<TDictionary> dictionariesToAdd = new ArrayList<>();

        //加入固定字典项
        Map<String, Pair<String, List<Item>>> fixedDictMap = FixedDictManager.getFixedDictMap();
        for (Map.Entry<String, Pair<String, List<Item>>> e : fixedDictMap.entrySet()) {
            List<Item> subCodes = caches.get(e.getKey());
            List<Item> fixedSubCodes = e.getValue().getValue();
            int order = 0;
            if (subCodes == null) {
                caches.put(e.getKey(), fixedSubCodes);
                TDictionary dict = new TDictionary();
                dict.setIsFixed(true);
                dict.setType("dict");
                dict.setName(e.getValue().getKey());
                dict.setSn(e.getKey());
                dict.setUpdateTime(new Date());
                dictionariesToAdd.add(dict);
                //addSub
                for (Item item : fixedSubCodes) {
                    TDictionary sub = new TDictionary();
                    sub.setIsFixed(true);
                    sub.setType(e.getKey());
                    sub.setName(item.getTitle());
                    sub.setSn(item.getKey());
                    sub.setUpdateTime(new Date());
                    sub.setRank(order++);
                    dictionariesToAdd.add(sub);
                }
            } else {
                Map<String, Item> codesMap = CollectionUtil.toKeyMap(subCodes, Item::getKey);
                for(Item item:fixedSubCodes){
                    order++;
                    if(codesMap.containsKey(item.getKey())){

                    }else{
                        //如果是新增也加进去
                        TDictionary sub = new TDictionary();
                        sub.setIsFixed(true);
                        sub.setType(e.getKey());
                        sub.setName(item.getTitle());
                        sub.setSn(item.getKey());
                        sub.setUpdateTime(new Date());
                        sub.setRank(order++);
                        dictionariesToAdd.add(sub);
                        subCodes.add(item);
                    }
                }
            }

        }

        dictCache = caches;
        if (!dictionariesToAdd.isEmpty()) {
            dao.saveAll(dictionariesToAdd);
        }
    }

    //建立地区缓存
    public void buildDistrictCache() {
        List<Map> data = dao.findBySql("select code _key,Name title,ParentCode parent,CodeOrder _order from zddistrict", new HashMap<>(), Map.class);
        Map root = new HashMap();
        root.put("key", "-");
        data.add(0, root);
        districts = buildTree(data);
    }

    public List<Item> getDistrict(String parent) {
        Item item = districts.get(parent);
        if (item == null || item.getChildren() == null) {
            return new ArrayList();
        }
        return copy0(item.getChildren());
    }

    public List<Item> getBaranchs(String parent) {
        Item item = baranchs.get(parent);
        if (item == null || item.getChildren() == null) {
            return new ArrayList();
        }
        return copy0(item.getChildren());
    }

    private List<Item> copy0(List<Item> data) {
        return data.stream()
                .map(it -> new Item(it.getKey(), it.getTitle()))
                .collect(Collectors.toList());
    }

    //建立机构缓存
    public void buildBranchCache() {
        List<Map> data = dao.findBySql("select sn _key,name title,psn parent,sort_rank _order from t_branch", new HashMap<>(), Map.class);
        baranchs = buildTree(data);
    }

    private Map<String, Item> buildTree(List<Map> data) {
        Map<String, Item> map = new HashMap();
        for (Map m : data) {

            String title = (String) m.get("title");
            String key = (String) m.get("key");
            String parent = (String) m.get("parent");
            Object order = m.get("order");

            Item item = new Item(key, title);
            item.setParent(parent);
            if (order == null) {
                item.setOrder(0);
            } else {
                item.setOrder(Integer.valueOf(order.toString()));
            }
            map.put(key, item);
        }
        for (Item item : map.values()) {
            Item parent = map.get(item.getParent());
            if (parent != null) {
                if (parent.getChildren() == null) {
                    parent.setChildren(new ArrayList());
                }
                parent.getChildren().add(item);
            }
        }
        for (Item item : map.values()) {
            if (item.getChildren() != null) {
                Collections.shuffle(item.getChildren());
            }
        }
        return map;
    }

    public Map<String, String> getByType(String type) {
        Locale locale= LocaleUtil.getLocale();
        List<Item> data = dictCache.get(type);

        Map result = new HashMap<>();
        if (data == null) {
            return result;
        }
        for (Item m : data) {
            result.put(m.getKey(),LocaleUtil.d(m.getTitle(),locale));
        }
        return result;
    }

    public Map<String, List<Item>> allCodes() {
        return dictCache;
    }

    @Override
    public void destroy() throws Exception {
        dictCache.clear();
        districts.clear();
        baranchs.clear();
    }
}
